// Learn TypeScript:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html

import CM from "../cache/CM";
import ICache from "../cache/ICache";
import MsgMgr from "../event/MsgMgr";
import { PROXY_ATTR_PATH, PROXY_INIT_PROXY_FUNC, PROXY_IS_INIT_PROXY, proxy } from "./Proxy";


export const SCRIPT_NAME = "scriptName"
export const MONITOR_LIST = "monitorList"
export function selfCls(target: any) {
    let frameInfo = cc["_RF"].peek();
    let script = frameInfo.script;
    cc.js.setClassName(script, target);
    target[SCRIPT_NAME] = ()=>{
        return script;
    };
}
//属性变化代理
export const nProxy = (target: object, propertyKey: string) => {
    target[PROXY_INIT_PROXY_FUNC] = (obj)=>{
        obj[PROXY_IS_INIT_PROXY] = true;
        let isRoot = obj["name"] != null;
        if (isRoot) {
            obj[PROXY_ATTR_PATH] = obj["name"]();
        }
        
        if (typeof(obj[propertyKey]) == "object") {
            obj[propertyKey][PROXY_ATTR_PATH] = `${obj[PROXY_ATTR_PATH]}/${propertyKey}`;
            obj[propertyKey] = proxy(obj[propertyKey]);
        }
        

    }
}

//属性变化绑定监听
export const monitor = (defaultPath?:string):PropertyDecorator=>{
    return (target: object, propertyKey: string)=>{
        target[MONITOR_LIST] = target[MONITOR_LIST] || [];
        target[MONITOR_LIST].push((obj, data?:ICache<any>, isClose?:boolean)=>{
            
            let array = propertyKey.split("_");
            let attrName = array[1];
            let path = defaultPath || (`${data[PROXY_ATTR_PATH]}/${attrName}`);
            let funcName = propertyKey;
            let dataName = path.split("/")[0];
            
            if (isClose) {
                MsgMgr.off(path, obj[funcName], obj);
            }else {
                data = CM.ins(CM).getByName(dataName);
                if (data) {
                    obj[funcName].call(obj, attrName, null, data[attrName])
                }
                MsgMgr.on(path, obj[funcName], obj);
            }
            
            
        })
    }
}


